package com.mazaiting.mock

import android.annotation.SuppressLint
import android.content.Context
import android.location.Criteria
import android.location.Location
import android.location.LocationManager
import android.location.LocationProvider
import android.os.Build
import android.os.Bundle
import android.os.SystemClock
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.MyLocationStyle
import com.amap.api.services.core.PoiItem
import com.amap.api.services.poisearch.PoiResult
import com.amap.api.services.poisearch.PoiSearch
import com.mazaiting.common.debug
import com.mazaiting.common.toast
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*
import kotlin.concurrent.thread


/**
 * 主页
 */
class MainActivity : AppCompatActivity(), PoiSearch.OnPoiSearchListener {
    /**
     * 初始化地图控制器对象
     */
    private var aMap: AMap? = null

    /**
     * 已经添加测试提供
     */
    private var hasAddTestProvider = false

    /**
     * 位置服务管理者
     */
    private var locationManager: LocationManager? = null

    /**
     * 坐标
     */
    private var latLng: LatLng? = null

    /**
     * 定义 Marker 点击事件监听
     */
    private val markerClickListener: AMap.OnMarkerClickListener =
        AMap.OnMarkerClickListener {
            debug(it)
            toast(it.title)
            setLocation(it.position)
            true
        }

    /**
     * 设置定位
     * @param latLng 坐标
     */
    private fun setLocation(latLng: LatLng?) {
        latLng?.let {
            if (canMockPosition()) {
//                aMap?.moveCamera(
//                    CameraUpdateFactory.newLatLng(latLng)
////                    CameraUpdateFactory.changeLatLng(latLng)
//                )
                this.latLng = fixedLatLng(it)
//                updateLocation()
            }
        }
    }

    /**
     * 修正坐标
     */
    private fun fixedLatLng(latLng: LatLng): LatLng? {
//        val pi =  Math.PI * 3000.0 / 180.0
////        val x = latLng.longitude - 0.0065
////        val y = latLng.latitude - 0.006
////        val z = sqrt(x * x + y * y) - 0.00002 * sin(y * pi)
////        val theta = atan2(y, x) - 0.000003 * cos(x * pi)
////        return LatLng(z * sin(theta), z * cos(theta))
//        val x = latLng.longitude
//        val y = latLng.latitude
//        val z = sqrt(x * x + y * y) + 0.00002 * sin(y * pi)
//        val theta = atan2(y, x) + 0.000003 * cos(x * pi)
//        return LatLng(z * sin(theta) + 0.006, z * cos(theta) + 0.0065)
//        return LatLng(latLng.latitude + 0.002715f, latLng.longitude - 0.0051f)
//        return LatLng(latLng.latitude + 0.002715f, latLng.longitude - 0.0051f)
//        return LatLng(latLng.latitude - 0.000875f, latLng.longitude - 0.002215f)
//        return PositionUtils.gps84ToGcj02(latLng.latitude, latLng.longitude)
        val newLatLng = Utils.gcj02towgs84(latLng.longitude, latLng.latitude)
        return LatLng(newLatLng[1], newLatLng[0])
    }

    /**
     * 更新位置
     */
    private fun updateLocation() {
        thread {
            while (true) {
                Thread.sleep(1000)
                if (hasAddTestProvider) {
                    this.latLng?.let {
                        val providerStr = LocationManager.GPS_PROVIDER
                        val mockLocation = Location(providerStr)
//                        41.163441,80.25921
//                        mockLocation.latitude = 41.159567
//                        mockLocation.longitude = 80.267103
//                        mockLocation.latitude = 41.1644157476854
//                        mockLocation.longitude = 80.26137825515224

//                        mockLocation.latitude = 41.163441
//                        mockLocation.longitude = 80.25921

                        mockLocation.latitude = it.latitude
                        mockLocation.longitude = it.longitude
                        mockLocation.accuracy = 0.1F // 精度（米）
                        mockLocation.time = Date().time // 本地时间
                        mockLocation.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
                        locationManager?.setTestProviderLocation(providerStr, mockLocation)
                    }
                } else {
                    debug("hasAddTestProvider: $hasAddTestProvider")
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mapView.onCreate(savedInstanceState)
        // 获取位置管理服务
        locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        initMap()
        initView()
        updateLocation()
    }

    /**
     * 初始化视图
     */
    private fun initView() {
        btnSearch.setOnClickListener {
            // 关键字
            val keyWord = etPlace.text.toString()
            val query = PoiSearch.Query(keyWord, "", "0997")
            // 设置每页最多返回多少条poiItem
            query.pageSize = 10
            // 设置查询页码
            query.pageNum = 0
            val poiSearch = PoiSearch(this, query)
            poiSearch.setOnPoiSearchListener(this)
            // 搜索
            poiSearch.searchPOIAsyn()
        }
    }

    /**
     * 初始化地图
     */
    private fun initMap() {
        if (null == aMap) {
            // 获取地图
            aMap = mapView.map
        }
        showLocation()
        initMapSettings()
    }

    /**
     * 初始化地图设备
     */
    private fun initMapSettings() {
        // 开始室内地图
        aMap?.showIndoorMap(true)
        // 设置缩放比例
        aMap?.moveCamera(CameraUpdateFactory.zoomTo(17.0F))
        // 绑定 Marker 被点击事件
        aMap?.setOnMarkerClickListener(markerClickListener)
        // 监听位置改变
        aMap?.setOnMyLocationChangeListener { it ->
            // latitude=41.159567#longitude=80.267103#province=新疆维吾尔自治区#city=阿克苏地区#district=阿克苏市#cityCode=0997#adCode=652901#address=新疆维吾尔自治区阿克苏地区阿克苏市水韵路靠近交通银行(阿克苏分行)#country=中国#road=水韵路#poiName=交通银行(阿克苏分行)#street=水韵路#streetNum=32号#aoiName=信合大厦#poiid=#floor=#errorCode=0#errorInfo=success#locationDetail=-1 #csid:95256fe08fe246a2b2dc31272bf21101#locationType=5
            debug(it)
        }
//        https://restapi.amap.com/v3/place/text?s=rsv3&children=&key=8325164e247e15eea68b59e89200988b&page=1&offset=10&city=652900&language=zh_cn&callback=jsonp_694207_&platform=JS&logversion=2.0&sdkversion=1.3&appname=https%3A%2F%2Flbs.amap.com%2Fconsole%2Fshow%2Fpicker&csid=AD8A6B5C-5A22-4380-BDD2-F2CAA5A556D2&keywords=%E4%BF%A1%E5%90%88%E5%A4%A7%E5%8E%A6
//        jsonp_694207_({"status":"1","count":"52","info":"OK","infocode":"10000","suggestion":{"keywords":[],"cities":[]},"pois":[{"id":"B0FFF3WRVD","parent":[],"childtype":[],"name":"信合大厦","type":"商务住宅;楼宇;商务写字楼","typecode":"120201","biz_type":[],"address":"南大街35号","location":"80.267589,41.159357","tel":"0997-2628926","distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"0","poiweight":[],"photos":[]},{"id":"BV10963638","parent":[],"childtype":[],"name":"信合大厦站(公交站)","type":"交通设施服务;公交车站;公交车站相关","typecode":"150700","biz_type":[],"address":"16路;18路环线;2路;3路;7路内环;9路;晚间公交专线一号线;晚间公交专线二号线","location":"80.268051,41.160000","tel":[],"distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"2","poiweight":[],"photos":[]},{"id":"B0FFHLKV0Q","parent":"B0FFF3WRVD","childtype":"308","name":"信合大厦A座","type":"商务住宅;楼宇;商务写字楼","typecode":"120201","biz_type":[],"address":"英巴扎街道水韵路水韵明珠信合大厦","location":"80.266968,41.159466","tel":[],"distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"0","poiweight":[],"photos":[]},{"id":"B0FFKEQTRI","parent":"B0FFF3WRVD","childtype":"101","name":"信合大厦(西北门)","type":"通行设施;临街院门;临街院门","typecode":"991400","biz_type":[],"address":"文化路与水韵路交叉口西南150米","location":"80.266732,41.159358","tel":[],"distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"2","poiweight":[],"photos":[]},{"id":"B0FFK55H9D","parent":"B0FFF3WRVD","childtype":"101","name":"信合大厦(东南门)","type":"通行设施;临街院门;临街院门","typecode":"991400","biz_type":[],"address":"文化路与水韵路交叉口南150米","location":"80.267945,41.159336","tel":[],"distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"2","poiweight":[],"photos":[]},{"id":"B0FFLO2JDH","parent":"B0FFF3WRVD","childtype":"202","name":"阿克苏农商行","type":"购物服务;专卖店;专营店","typecode":"061200","biz_type":[],"address":"信合大厦","location":"80.266968,41.159466","tel":[],"distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"0","poiweight":[],"photos":[]},{"id":"B0FFJVJJJ9","parent":"B0FFF3WRVD","childtype":"202","name":"阿克苏农商银行","type":"金融保险服务;银行;农村商业银行","typecode":"160121","biz_type":[],"address":"信合大厦","location":"80.267576,41.159801","tel":[],"distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"2","poiweight":[],"photos":[]},{"id":"B0FFLEM7ZU","parent":[],"childtype":[],"name":"圣思梵皮肤管理(信合大厦B座)","type":"生活服务;美容美发店;美容美发店","typecode":"071100","biz_type":[],"address":"南大街信合大厦B座17层","location":"80.267646,41.159350","tel":"15599737772","distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"0","poiweight":[],"photos":[]},{"id":"B0FFHE6H7C","parent":"B0FFF3WRVD","childtype":"202","name":"新疆农信阿克苏农商银行","type":"金融保险服务;银行;农村商业银行","typecode":"160121","biz_type":[],"address":"信合大厦1楼","location":"80.267765,41.159396","tel":[],"distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"2","poiweight":[],"photos":[{"url":"http://store.is.autonavi.com/showpic/4c3630fff78710b3f4c45b2b9458259d","provider":[],"title":[]}]},{"id":"B0FFKZUGO8","parent":[],"childtype":[],"name":"水韵社区","type":"商务住宅;住宅区;住宅小区","typecode":"120302","biz_type":[],"address":"水韵路信合大厦","location":"80.266976,41.159433","tel":[],"distance":[],"biz_ext":{"rating":[],"cost":[]},"pname":"新疆维吾尔自治区","cityname":"阿克苏地区","adname":"阿克苏市","importance":[],"shopid":[],"shopinfo":"0","poiweight":[],"photos":[]}]})
    }

    /**
     * 设置显示定位
     */
    private fun showLocation() {
        val myLocationStyle =
            MyLocationStyle()
                // 设置显示风格, 定位一次
                .myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE)
                // 设置连续定位间隔时间
                .interval(5000L)
        // 设置定位蓝点风格
        aMap?.myLocationStyle = myLocationStyle
        // 设置为true表示启动显示定位蓝点，false表示隐藏定位蓝点并不进行定位，默认是false。
        aMap?.isMyLocationEnabled = true

    }

    override fun onResume() {
        super.onResume()
        mapView.onResume()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mapView.onSaveInstanceState(outState)
    }

    override fun onPause() {
        super.onPause()
        mapView.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        mapView.onDestroy()
    }

    override fun onPoiItemSearched(item: PoiItem?, code: Int) {

    }

    /**
     * 搜索完成回调
     */
    override fun onPoiSearched(item: PoiResult?, code: Int) {
        if (code == 1000) {
            // 解析result获取POI信息
            // [电力小区, 阿克苏市晶水路电力小区, 电力小区1号, 电力小区, 电力小区2号, 阿克苏市健康路电力小区, 电力小区1号(南门), 阿克苏市晶水路电力小区(西南门), 西北电力(华能小区西), 圆通速递(南城分部)]
            debug(item?.pois.toString())
            item?.pois?.map { poi ->
                // 新疆维吾尔自治区,阿克苏地区,沙雅县,电力小区,新世纪步行街与萨依巴格北路交叉口北100米
                debug(
                    poi.provinceName + "," + poi.cityName + "," + poi.adName + "," + poi.title +
                            "," + poi.snippet + ", latitude: " + poi.latLonPoint.latitude +
                            ", longitude: " + poi.latLonPoint.longitude
                )
                val latLonPoint = poi.latLonPoint
                val latLng = LatLng(latLonPoint.latitude, latLonPoint.longitude)
                // 添加标记物
                aMap?.addMarker(
                    MarkerOptions().position(latLng).title(poi.title).snippet(poi.snippet)
                )
            }
        }
    }


    /**
     * 初始化位置信息
     */
    @SuppressLint("MissingPermission")
    private fun canMockPosition(): Boolean {
//        locationManager?.requestLocationUpdates(
//            LocationManager.GPS_PROVIDER,
//            1000L,
//            10F,
//            object :
//                LocationListener {
//                override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {
//                    debug("onStatusChanged")
//                }
//
//                @SuppressLint("MissingPermission")
//                override fun onProviderEnabled(provider: String) {
//                    debug("onProviderEnabled")
//                    val lastKnownLocation = locationManager?.getLastKnownLocation(provider)
//                    upData(lastKnownLocation)
//                }
//
//                override fun onProviderDisabled(provider: String) {
//                    debug("onProviderDisabled")
//                }
//
//                override fun onLocationChanged(location: Location) {
//                    // 当GPS定位信息发生改变时，更新位置
//                    debug("onLocationChanged")
//                    upData(location)
//                }
//            })
        // 判断是否开启允许模拟位置
        // Android 6.0以下，通过Setting.Secure.ALLOW_MOCK_LOCATION判断
        // Android 6.0及以上，需要【选择模拟位置信息应用】，未找到方法，因此通过addTestProvider是否可用判断
        var canMockPosition =
            (Settings.Secure.getInt(contentResolver, Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0)
                    || Build.VERSION.SDK_INT >= Build.VERSION_CODES.M

        if (canMockPosition && !hasAddTestProvider) {
            try {
                // gps 提供
                val providerStr = LocationManager.GPS_PROVIDER
                // 位置提供者
                val provider = locationManager?.getProvider(providerStr)
                if (null != provider) {
                    // 添加测试位置提供
                    locationManager?.addTestProvider(
                        provider.name,
                        provider.requiresNetwork(),
                        provider.requiresSatellite(),
                        provider.requiresCell(),
                        provider.hasMonetaryCost(),
                        provider.supportsAltitude(),
                        provider.supportsSpeed(),
                        provider.supportsBearing(),
                        provider.powerRequirement,
                        provider.accuracy
                    )
                } else {
                    locationManager?.addTestProvider(
                        providerStr, true, true, false,
                        false, true, true, true, Criteria.POWER_HIGH,
                        Criteria.ACCURACY_FINE
                    )
//        if (providerStr.equals(LocationManager.GPS_PROVIDER)) {
//          locationManager.addTestProvider(
//            providerStr
//            , true, true, false, false, true, true, true
//            , Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
//        } else if (providerStr.equals(LocationManager.NETWORK_PROVIDER)) {
//          locationManager.addTestProvider(
//            providerStr
//            , true, false, true, false, false, false, false
//            , Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
//        } else {
//          locationManager.addTestProvider(
//            providerStr
//            , false, false, false, false, true, true, true
//            , Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
//        }
                }
                // 设置测试提供可用
                locationManager?.setTestProviderEnabled(providerStr, true)
                // 设置测试提供状态
                locationManager?.setTestProviderStatus(
                    providerStr,
                    LocationProvider.AVAILABLE,
                    null,
                    System.currentTimeMillis()
                )
                // 模拟位置可用
                hasAddTestProvider = true
                canMockPosition = true
            } catch (e: Exception) {
                canMockPosition = false
            }
        } else {
            debug("未开启模拟位置")
            canMockPosition = false
        }
        return canMockPosition
    }
}
